package com.kfh.ybracelet.sim;

import android.app.ProgressDialog;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.kfh.ybracelet.R;
import com.kfh.ybracelet.base.BaseActivity;
import com.kfh.ybracelet.bean.AliIdBean;
import com.kfh.ybracelet.bean.IdInfo;
import com.kfh.ybracelet.bean.UploadBean;
import com.kfh.ybracelet.client.constant.Constants;
import com.kfh.ybracelet.net.HttpUtil;
import com.kfh.ybracelet.utils.CommonUtils;
import com.kfh.ybracelet.utils.Constant;
import com.kfh.ybracelet.utils.LogUtil;
import com.kfh.ybracelet.widget.ActionSheetDialog;
import com.qiniu.android.http.ResponseInfo;
import com.qiniu.android.storage.UpCompletionHandler;
import com.qiniu.android.storage.UploadManager;

import org.json.JSONArray;
import org.json.JSONException;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import Decoder.BASE64Encoder;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;

/**
 * 身份证上传页面
 * Created by Aaron on 16/9/14.
 */
public class IDConfirmActivity extends BaseActivity {

    private android.widget.ImageView btn1;
    private android.widget.ImageView image1;
    private android.widget.ImageView btn2;
    private android.widget.ImageView image2;
    private android.widget.ImageView btn3;
    private android.widget.ImageView image3;
    private android.widget.Button next;

    private String photoFront;//身份证正面照 (本地)
    private String photoBack;//身份证反面照 (本地)
    private String photoHold;//手持身份证照片 (本地)

    private String photoFrontUrl;//身份证正面照 (网络)
    private String photoBackUrl;//身份证反面照 (网络)
    private String photoHoldUrl;//手持身份证照片 (网络)

    private final String TAG = getClass().getSimpleName();

    private String phoneNum;//实名验证的手机号码

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_id_confirm);

        phoneNum = getIntent().getStringExtra("phoneNum");

        initView();

    }

    private void initView() {

        ImageView iv_left = (ImageView) findViewById(R.id.iv_left);
        iv_left.setOnClickListener(this);

        TextView tv_title = (TextView) findViewById(R.id.tv_title);
        tv_title.setText(getResources().getString(R.string.identity));

        this.next = (Button) findViewById(R.id.next);
        this.image3 = (ImageView) findViewById(R.id.image3);
        this.btn3 = (ImageView) findViewById(R.id.btn3);
        this.image2 = (ImageView) findViewById(R.id.image2);
        this.btn2 = (ImageView) findViewById(R.id.btn2);
        this.image1 = (ImageView) findViewById(R.id.image1);
        this.btn1 = (ImageView) findViewById(R.id.btn1);

        next.setOnClickListener(this);
        btn1.setOnClickListener(this);
        btn2.setOnClickListener(this);
        btn3.setOnClickListener(this);

    }

    private static final String STYLE_FRONT = "front";
    private static final String STYLE_BACK = "back";
    private static final String STYLE_HOLD = "hold";

    private static final int ID_PHOTO_FRONT_TAKE = 0x91;//身份证正面照 (拍照)
    private static final int ID_PHOTO_FRONT_CHOOSE = 0x92;//身份证正面照 (相册选择)
    private static final int ID_PHOTO_BACK_TAKE = 0x93;//身份证反面照 (拍照)
    private static final int ID_PHOTO_BACK_CHOOSE = 0x94;//身份证反面照 (相册选择)
    private static final int ID_PHOTO_PEOPLE_TAKE = 0x95;//手持身份证正面照 (拍照)
    private static final int ID_PHOTO_PEOPLE_CHOOSE = 0x96;//手持身份证正面照 (相册选择)

    @Override
    public void widgetClick(View v) {

        switch (v.getId()) {

            case R.id.iv_left:
                finish();
                break;

            case R.id.btn1://身份证正面照

                showChoose(STYLE_FRONT);

                break;

            case R.id.btn2://身份证反面照

                showChoose(STYLE_BACK);

                break;

            case R.id.btn3://手持身份证照

                showChoose(STYLE_HOLD);

                break;

            case R.id.next://下一步

                //验证身份证信息
                try {
                    confirmIdInfo();
                } catch (IOException e) {
                    e.printStackTrace();
                    showToast("身份证信息获取失败");
                    LogUtil.e(TAG, " ===  出错 IOException");
                } catch (Exception e) {
                    e.printStackTrace();
                    showToast("身份证信息获取失败");
                    LogUtil.e(TAG, " ===  出错 Exception");
                }

                break;

        }

    }

    private ProgressDialog show;

    private void confirmIdInfo() throws Exception {

        if (TextUtils.isEmpty(photoFrontUrl)) {
            showToast("请上传身份证正面照");
            return;
        }

        if (TextUtils.isEmpty(photoFrontUrl)) {
            showToast("请上传身份证背面照");
            return;
        }

        if (TextUtils.isEmpty(photoFrontUrl)) {
            showToast("请上传手持身份证照片");
            return;
        }

        discernInfo();

    }

    /**
     * 识别身份信息
     */
    private void discernInfo() {

        show = ProgressDialog.show(this, "请稍候", "识别中...");

        new Thread(new Runnable() {
            @Override
            public void run() {

                try {

                    byte[] bytesFront = compressPhoto(photoFront);
                    byte[] bytesBack = compressPhoto(photoBack);

                    LogUtil.e(TAG, "上传的图片的大小 bytesFront:" + bytesFront.length + ",bytesBack:" + bytesBack.length);

                    if (bytesFront.length > (1024 * 1024 * 1.5)) {
                        showToast("身份证正面照过大,请重新上传");
                        dismissDia();
                        return;
                    }

                    if (bytesBack.length > (1024 * 1024 * 1.5)) {
                        showToast("身份证反面照过大,请重新上传");
                        dismissDia();
                        return;
                    }

                    String encodeFront = new BASE64Encoder().encode(bytesFront);
                    String encodeBack = new BASE64Encoder().encode(bytesBack);

                    LogUtil.e(TAG, "图片地址:" + photoBack + ",\n" + ",front:" + photoFront);

                    final String photoInfo = getPhotoInfo(encodeFront, encodeBack);

                    getAliyunInfo(photoInfo);

                } catch (Exception e) {
                    e.printStackTrace();
                    showToast("身份信息识别失败");
                    dismissDia();
                }

            }

        }).start();
    }

    private void dismissDia() {
        if (show != null && show.isShowing())
            show.dismiss();
    }

    /**
     * 上传身份证信息到阿里云
     *
     * @param photoInfo
     */
    private void getAliyunInfo(final String photoInfo) {

//        Runnable runnable = new Runnable() {
//            @Override
//            public void run() {
//                String getPath = "/testhttp/postbyte";
        String getPath = "/rest/160601/ocr/ocr_idcard.json";

        Map<String, String> getQueryParams = new HashMap<>();
//                getQueryParams.put("QueryName" , "TestQueryNameVlaue");

        Map<String, String> getHeaderParams = new HashMap<>();
//                getHeaderParams.put("TestPostHeader" , "HTTP头");

        String content = photoInfo;

        com.kfh.ybracelet.client.HttpUtil.getInstance().httpPostBytes(getPath, null, getQueryParams,
                content.getBytes(Constants.CLOUDAPI_ENCODING), getHeaderParams, new Callback() {

                    @Override
                    public void onFailure(Call call, IOException e) {
                        LogUtil.e(TAG, "onFailure :" + e.getMessage());
                        showToast("身份信息识别失败,请重新上传");
                        dismissDia();
                    }

                    @Override
                    public void onResponse(Call call, final Response response) throws IOException {
                        dismissDia();

                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                try {

//                                    LogUtil.e(TAG, "onResponse :" + response.message() + "\n result:" + new String(response.body().bytes(), Constants.CLOUDAPI_ENCODING));
                                    handleReuslt(new String(response.body().bytes(), Constants.CLOUDAPI_ENCODING));

                                } catch (IOException e) {
                                    e.printStackTrace();
                                    showToast("身份信息获取失败");
                                }
                            }
                        });
//                        String result = new String(response.body().bytes(), Constants.CLOUDAPI_ENCODING);
//                        LogUtil.e(TAG, "onResponse :" + response.message() + "\n result:" + result);

                    }
                });

//            }
//        };
//        new Thread(runnable).start();
    }

    /**
     * 处理返回的结果
     *
     * @param result
     */
    private void handleReuslt(String result) {

        try {
//            org.json.JSONObject or = new org.json.JSONObject(result);

            if (TextUtils.isEmpty(result)) {
                showToast("身份证信息识别失败");
                return;
            }

            JSONArray outputs = new org.json.JSONObject(result).getJSONArray("outputs");

            IdInfo idInfo = new IdInfo();

            for (int i = 0; i < outputs.length(); i++) {

                org.json.JSONObject o = (org.json.JSONObject) outputs.get(i);

                org.json.JSONObject outputValue = o.getJSONObject("outputValue");

                String string = outputValue.getString("dataValue");

                org.json.JSONObject info = new org.json.JSONObject(string);

                String config_str = info.getString("config_str");

                String side = new org.json.JSONObject(config_str).getString("side");

                if ("back".equals(side)) { //反面信息

                    if (info.getBoolean("success")) {
                        idInfo.setStart_date(info.getString("start_date"));
                        idInfo.setEnd_date(info.getString("end_date"));
                    } else {
                        showToast("反面照识别失败");
                        return;
                    }

                } else if ("face".equals(side)) {//正面信息

                    if (info.getBoolean("success")) {
                        idInfo.setAddress(info.getString("address"));
                        idInfo.setBirth(info.getString("birth"));
                        idInfo.setName(info.getString("name"));
                        idInfo.setNationality(info.getString("nationality"));
                        idInfo.setNum(info.getString("num"));
                        idInfo.setSex(info.getString("sex"));

                        LogUtil.e(TAG, "返回的信息:" + "adddress:" + info.getString("address")
                                + "\n birth:" + info.getString("birth")
                                + "\n name:" + info.getString("name")
                                + "\n nationality:" + info.getString("nationality")
                                + "\n num:" + info.getString("num")
                                + "\n sex:" + info.getString("sex"));
                    } else {
                        showToast("正面照识别失败");
                        return;
                    }

                }

            }

            Intent mIntent = new Intent(IDConfirmActivity.this, InfoConfirmActivity.class);
            mIntent.putExtra("phoneNum", phoneNum);
            mIntent.putExtra("info", idInfo);
            mIntent.putExtra("sideFace", photoFrontUrl);
            mIntent.putExtra("sideBack", photoBackUrl);
            mIntent.putExtra("sideHold", photoHoldUrl);
            startActivity(mIntent);

        } catch (JSONException e) {
            e.printStackTrace();
        }

    }

    /**
     * 获取到上传到阿里云的json串
     *
     * @param encodeFront
     * @param encodeBack
     * @return
     */
    private String getPhotoInfo(String encodeFront, String encodeBack) {

        AliIdBean aliIdBean = new AliIdBean();

        AliIdBean.InputsEntity inputsEntityFront = aliIdBean.new InputsEntity();

        AliIdBean.InputsEntity.ImageEntity imageFront = inputsEntityFront.new ImageEntity();
        imageFront.setDataType(50);
        imageFront.setDataValue(encodeFront);//图片base64编码

        AliIdBean.InputsEntity.ConfigureEntity configureFront = inputsEntityFront.new ConfigureEntity();
        configureFront.setDataType(50);
        configureFront.setDataValue("{\"side\":\"face\"}");

        inputsEntityFront.setImage(imageFront);
        inputsEntityFront.setConfigure(configureFront);

        AliIdBean.InputsEntity inputsEntityBack = aliIdBean.new InputsEntity();

        AliIdBean.InputsEntity.ImageEntity imageBack = inputsEntityBack.new ImageEntity();
        imageBack.setDataType(50);
        imageBack.setDataValue(encodeBack);//图片base64编码

        AliIdBean.InputsEntity.ConfigureEntity configureBack = inputsEntityBack.new ConfigureEntity();
        configureBack.setDataType(50);
        configureBack.setDataValue("{\"side\":\"back\"}");

        inputsEntityBack.setImage(imageBack);
        inputsEntityBack.setConfigure(configureBack);

        List<AliIdBean.InputsEntity> inputs = new ArrayList<>();
        inputs.add(inputsEntityFront);
        inputs.add(inputsEntityBack);

        aliIdBean.setInputs(inputs);

        return JSON.toJSONString(aliIdBean);

    }

    /**
     * 压缩图片
     */
    private byte[] compressPhoto(String srcPath) throws Exception {

        byte[] aByte = CommonUtils.getByte(new File(srcPath));
        //小于1.5M的图片 不用压缩
        if (aByte.length < 1024 * 1024 * 1.5) {
            LogUtil.e(TAG, "小于1.5M 未压缩");
            return CommonUtils.getByte(new File(srcPath));
        }

        int scale = 1;
//
        LogUtil.e(TAG, "\n图片的大小" + aByte.length);

        if ((1024 * 1024 * 3) > aByte.length && aByte.length >= (1024 * 1024 * 2)) {
            scale = 2;
        } else if ((1024 * 1024 * 4) > aByte.length && aByte.length >= (1024 * 1024 * 3)) {
            scale = 3;
        } else if ((1024 * 1024 * 5) > aByte.length && aByte.length >= (1024 * 1024 * 4)) {
            scale = 4;
        } else if ((1024 * 1024 * 6) > aByte.length && aByte.length >= (1024 * 1024 * 5)) {
            scale = 5;
        } else {
            scale = 10;
        }

        aByte = null;

        //TODO  计算出压缩比
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        newOpts.inJustDecodeBounds = true;//只读边,不读内容
        Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);

        newOpts.inJustDecodeBounds = false;

        newOpts.inSampleSize = ++scale;//设置采样率

        LogUtil.e(TAG, " 压缩比率 : " + scale);

        newOpts.inPreferredConfig = Bitmap.Config.RGB_565;//
        newOpts.inPurgeable = true;// 同时设置才会有效
        newOpts.inInputShareable = true;//。当系统内存不够时候图片自动被回收

        bitmap = BitmapFactory.decodeFile(srcPath, newOpts);

        String path = Environment.getExternalStorageDirectory().getPath() + Constant.PHOTO_PATH + "/" + UUID.randomUUID().toString();

        CommonUtils.saveBitmap2Local(bitmap, path);

//        return CommonUtils.compressByte(BitmapFactory.decodeFile(srcPath, newOpts));
        byte[] bytes = CommonUtils.getByte(new File(path));

        LogUtil.e(TAG, "上传的身份证照片的大小: " + bytes.length);

        bitmap.recycle();

        return bytes;

    }

    /**
     * 弹出选择照片的对话框
     */
    @Deprecated
    protected void showChoose(final String style) {

        new ActionSheetDialog(this)
                .builder()
                .setCancelable(true)
                .setCanceledOnTouchOutside(true)
                .addSheetItem("拍照", ActionSheetDialog.SheetItemColor.Blue,
                        new ActionSheetDialog.OnSheetItemClickListener() {
                            @Override
                            public void onClick(int which) {

                                // 拍照
                                switch (style) {

                                    case STYLE_FRONT:
                                        //身份证正面拍照
                                        getTakePhoto(ID_PHOTO_FRONT_TAKE);
                                        break;
                                    case STYLE_BACK:
                                        //身份证反面拍照
                                        getTakePhoto(ID_PHOTO_BACK_TAKE);
                                        break;
                                    case STYLE_HOLD:
                                        //手持身份证拍照
                                        getTakePhoto(ID_PHOTO_PEOPLE_TAKE);
                                        break;

                                }

                            }

                        })
                .addSheetItem("去相册选择", ActionSheetDialog.SheetItemColor.Blue,
                        new ActionSheetDialog.OnSheetItemClickListener() {
                            @Override
                            public void onClick(int which) {
                                // 从相册中选择
//                                getFromPhotoAlbum();
                                switch (style) {

                                    case STYLE_FRONT:
                                        // 相册选择 身份证正面
                                        getFromPhotoAlbum(ID_PHOTO_FRONT_CHOOSE);
                                        break;
                                    case STYLE_BACK:
                                        // 相册选择 身份证反面
                                        getFromPhotoAlbum(ID_PHOTO_BACK_CHOOSE);
                                        break;
                                    case STYLE_HOLD:
                                        // 相册选择 手持身份证
                                        getFromPhotoAlbum(ID_PHOTO_PEOPLE_CHOOSE);
                                        break;

                                }
                            }
                        }).show();

    }

    /*拍照的文件保存的位置*/
    private File currentFile;

    /**
     * 拍照
     */
    private void getTakePhoto(int code) {

        String cacheDir = Environment.getExternalStorageDirectory().getPath() + Constant.PHOTO_PATH;
        File photoFile = new File(cacheDir);
        //文件夹不存在就创建文件夹
        if (!photoFile.exists()) {
            photoFile.mkdirs();
        }
        //创建存放图片的jpg文件
        currentFile = new File(photoFile, System.currentTimeMillis() + ".jpg");

        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(currentFile));
        startActivityForResult(intent, code);

    }

    /**
     * 从相册中选择
     */
    private void getFromPhotoAlbum(int code) {

        Intent mIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(mIntent, code);

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        try {
            switch (requestCode) {

                case ID_PHOTO_FRONT_TAKE: //= 0x91;//身份证正面照 (拍照)

                    //上传图片
                    if (currentFile != null && currentFile.exists()) {
                        getUploadToken(CommonUtils.getByte(currentFile), STYLE_FRONT);
                        photoFront = currentFile.getAbsolutePath();
                    }

                    break;

                case ID_PHOTO_FRONT_CHOOSE:// = 0x92;//身份证正面照 (相册选择)

                    if (data == null)
                        return;

                    photoFront = getChoosedPhoto(data, STYLE_FRONT);

                    break;

                case ID_PHOTO_BACK_TAKE:// = 0x93;//身份证反面照 (拍照)

                    //上传图片
                    if (currentFile != null && currentFile.exists()) {
                        getUploadToken(CommonUtils.getByte(currentFile), STYLE_BACK);
                        photoBack = currentFile.getAbsolutePath();
                    }

                    break;

                case ID_PHOTO_BACK_CHOOSE:// = 0x94;//身份证反面照 (相册选择)

                    if (data == null)
                        return;

                    photoBack = getChoosedPhoto(data, STYLE_BACK);

                    break;

                case ID_PHOTO_PEOPLE_TAKE:// = 0x95;//手持身份证正面照 (拍照)

                    //上传图片
                    if (currentFile != null && currentFile.exists()) {
                        getUploadToken(CommonUtils.getByte(currentFile), STYLE_HOLD);
                        photoHold = currentFile.getAbsolutePath();
                    }

                    break;

                case ID_PHOTO_PEOPLE_CHOOSE: // = 0x96;//手持身份证正面照 (相册选择)

                    if (data == null)
                        return;

                    photoHold = getChoosedPhoto(data, STYLE_HOLD);

                    break;

            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * @param data
     * @param style 正面照 or 反面照 or 手持照
     * @return
     * @throws Exception
     */
    private String getChoosedPhoto(Intent data, String style) throws Exception {
        Uri selectedImage = data.getData();
        String[] filePathColumn = {MediaStore.Images.Media.DATA};

        Cursor cursor = getContentResolver().query(selectedImage,
                filePathColumn, null, null, null);
        cursor.moveToFirst();

        int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
        String picturePath = cursor.getString(columnIndex);
        cursor.close();

        LogUtil.e(TAG, "选择的图片地址:" + picturePath);

        getUploadToken(CommonUtils.getByte(new File(picturePath)), style);

        return picturePath;
    }

    /**
     * 上传图片
     *
     * @param bytes
     * @param photoStyle 照片类型 (正面照, 反面照, 手持身份证照)
     */
    private void getUploadToken(final byte[] bytes, final String photoStyle) {

        JSONObject j = new JSONObject();
        j.put("token", sp.getString(Constant.TOKEN, ""));

        HttpUtil.setPostRequest("加载中...", IDConfirmActivity.this, Constant.WEB_ROOT + Constant.UPLOADTOKEN,
                j.toJSONString(), getClass().getName(), new HttpUtil.SuccessListener() {

                    private ProgressDialog progress;

                    @Override
                    public void setOnSuccessListener(String str) {

//                        LogUtil.e("tag", "返回的token==" + str);

                        final UploadBean uploadBean = JSONObject.parseObject(str, UploadBean.class);

//                        if (uploadBean.code == Constant.STATUS_SUCCESS) {

                            UploadManager uploadManager = new UploadManager();

                            progress = ProgressDialog.show(IDConfirmActivity.this, "提示", "图片上传中...");

                            uploadManager.put(bytes, uploadBean.path, uploadBean.token,
                                    new UpCompletionHandler() {

                                        @Override
                                        public void complete(String s, ResponseInfo responseInfo, org.json.JSONObject jsonObject) {

                                            if (progress != null && progress.isShowing())
                                                progress.dismiss();

                                            if (responseInfo.isOK()) {

                                                showToast("上传成功");

                                                String imageUrl = uploadBean.domain + uploadBean.path + uploadBean._S;

                                                LogUtil.e(TAG, "imageUrl : " + uploadBean.domain + uploadBean.path + "" +
//                                                        "\n thumb:" + imageUrl + uploadBean.thumb +
                                                        "\n" + "s:" + imageUrl);

                                                switch (photoStyle) {

                                                    case STYLE_FRONT://身份证正面

                                                        photoFrontUrl = imageUrl;
                                                        showImage(imageUrl, btn1);

                                                        break;

                                                    case STYLE_BACK://身份证反面

                                                        photoBackUrl = imageUrl;
                                                        showImage(imageUrl, btn2);

                                                        break;

                                                    case STYLE_HOLD://手持身份证

                                                        photoHoldUrl = imageUrl;
                                                        showImage(imageUrl, btn3);

                                                        break;

                                                }
//
                                            } else {
                                                showToast("图片上传失败");

                                                switch (photoStyle) {

                                                    case STYLE_FRONT://身份证正面
                                                        photoFrontUrl = "";
                                                        break;

                                                    case STYLE_BACK://身份证反面
                                                        photoBackUrl = "";
                                                        break;

                                                    case STYLE_HOLD://手持身份证
                                                        photoHoldUrl = "";
                                                        break;

                                                }

                                            }

                                        }

                                    }, null);

//                        } else {
//                            showToast(Constant.showErrorMsg(uploadBean.code, IDConfirmActivity.this));
//                        }

                    }
                }, null);

    }

    /**
     * 显示上传后的缩略图
     *
     * @param imageUrl
     * @param imageView
     */
    private void showImage(String imageUrl, ImageView imageView) {

        Glide.with(getApplicationContext())
                .load(imageUrl)
                .dontAnimate().diskCacheStrategy(DiskCacheStrategy.SOURCE).fitCenter()
//                                                                .placeholder(R.mipmap.temp_pic)
                .into(imageView);
    }

}
